<route lang="json5">
{
  meta: {
    auth: true,
    label: '主窗口',
  },
}
</route>

<template>
  <div>
    <a-button v-if="!open" @click="handleOpen">打开小窗</a-button>
    <a-button v-else @click="handleClose">关闭小窗</a-button>
    <a-divider />
    <a-button :disabled="!open" @click="handleSend">postMessage</a-button>
    <a-divider />
    <div class="grid grid-cols-3 w-max gap-4">
      <div
        v-for="item in 9"
        @mouseenter="handleChangeActive(item)"
        @mouseleave="handleChangeActive(0)"
        :class="{
          ' bg-blue-100': active === item,
        }"
        class="h-12 w-12 bg-red-50 transition-all duration-200 cursor-pointer"
      ></div>
    </div>
    <a-divider />
    <p class="text-red-500 mt-2">点击打开小窗，发送消息，小窗可以收到消息（使用postMessage</p>
  </div>
</template>

<script lang="ts" setup>
let externalTools: any // 外部窗口对象
let onlineInterval: NodeJS.Timeout // 监听小窗状态
const channel = new BroadcastChannel('channel-PAKCHOI.XXXX')

const open = ref(false)
const active = ref(0)

function handleMessage({ data }: any) {
  if (!data.command) {
    Message.clear()
    Message.info(JSON.stringify(data))
  } else {
    switch (data.command) {
      case 'change-active':
        active.value = data.value
        break
    }
  }
}

function handleChangeActive(value: number) {
  active.value = value
  externalTools && externalTools.postMessage({ command: 'change-active', value })
}

function handleOpen() {
  if (externalTools && !externalTools.closed) return Message.error('小窗已打开！')
  const { origin } = window.location
  externalTools = window.open(`${origin}/childWin`, '', 'top=300,titlebar=no,toolbar=no,height=300,width=400')
  channel.addEventListener('message', handleMessage)
  open.value = true
  onlineInterval = setInterval(() => {
    if (!externalTools || externalTools.closed) {
      window.removeEventListener('message', handleMessage)
      clearInterval(onlineInterval)
      open.value = false
    }
  }, 500)
}

function handleSend() {
  if (!externalTools) return Message.error('小窗异常，请重新打开')
  externalTools.postMessage('吃了吗？')
}

function handleClose() {
  externalTools && externalTools.close()
  channel.removeEventListener('message', handleMessage)
}

onBeforeUnmount(handleClose)
</script>
